package com.genius.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.genius.annotation.Log;
import com.genius.annotation.PreFuncAuth;
import com.genius.annotation.PreInnerAuth;
import com.genius.auth.bo.RegisterBO;
import com.genius.core.JSONResult;
import com.genius.core.LoginUser;
import com.genius.enums.BusinessType;
import com.genius.enums.ResponseType;
import com.genius.exception.GraceException;
import com.genius.service.MenuService;
import com.genius.service.UserRoleService;
import com.genius.service.UserService;
import com.genius.system.bo.*;
import com.genius.system.pojo.Role;
import com.genius.system.pojo.User;
import com.genius.system.vo.UpdateUserVO;
import com.genius.utils.CheckUtils;
import com.genius.utils.PageUtils;
import com.genius.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

@RestController
@RequestMapping("/user")
@Api(value = "用户管理接口", tags = {"用于用户管理的接口"})
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private CheckUtils checkUtils;

    @PostMapping("/selectUserById")
    @ApiOperation(value = "查询用户（根据ID查询）",notes = "根据ID查询用户", httpMethod = "POST")
    public JSONResult selectUserById(@Valid @RequestBody SelectUserByIdBO selectUserByIdBO) {
        User user = userService.selectUserById(selectUserByIdBO.getUserId());
        UpdateUserVO updateUserVO = JSONUtil.parse(user).toBean(UpdateUserVO.class);
        updateUserVO.setPassword("*********");
        List<Role> roleList = user.getRoles();
        List<String> roleIds = new ArrayList<>();
        for(Role role:roleList){
            roleIds.add(role.getRoleId().toString());
        }
        updateUserVO.setRoleIds(roleIds);
        Map<String,Object> result = new HashMap<>();
        result.put("user",updateUserVO);
        return JSONResult.ok(result);
    }

    @PostMapping("/selectUserByPage")
    @ApiOperation(value = "查询用户（根据分页查询）",notes = "查询用户分页记录", httpMethod = "POST")
    @PreFuncAuth("SYS:USER:SELECT")
    public JSONResult selectUserByPage(@Valid @RequestBody SelectUserByPageBO selectUserByPageBO){
        int pageNum = selectUserByPageBO.getPageNum();
        int pageSize = selectUserByPageBO.getPageSize();
        User user = JSONUtil.parse(selectUserByPageBO).toBean(User.class);
        PageUtils.startPage(pageNum,pageSize);
        List<User> userList = userService.selectUserByPage(user);
        Map<String,Object> result = PageUtils.getResultTableData(userList);
        return JSONResult.ok(result);
    }

    @PostMapping("/insertUser")
    @PreFuncAuth("SYS:USER:INSERT")
    @ApiOperation(value = "添加用户",notes = "添加用户", httpMethod = "POST")
    public JSONResult insertUser(@Valid @RequestBody InsertUserBO insertUserBO) {
        checkUserExist(insertUserBO.getUsername());
        User user = JSONUtil.parse(insertUserBO).toBean(User.class);
        Long userId = IdUtil.getSnowflake().nextId();
        user.setUserId(userId);
        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        int rows = userService.insertUser(user);
        userRoleService.insertUserRole(userId, insertUserBO.getRoleIds());
        Map<String,Object> result = new HashMap<>();
        result.put("rows",rows);
        return JSONResult.ok(result);
    }

    @PostMapping("/updateUser")
    @PreFuncAuth("SYS:USER:UPDATE")
    @ApiOperation(value = "修改用户",notes = "修改用户", httpMethod = "POST")
    public JSONResult updateUser(@Valid @RequestBody UpdateUserBO updateUserBO) {
        User user = JSONUtil.parse(updateUserBO).toBean(User.class);
        user.setUpdateBy(SecurityUtils.getUsername());
        int rows = userService.updateUser(user);
        userRoleService.insertUserRole(updateUserBO.getUserId(), updateUserBO.getRoleIds());
        Map<String,Object> result = new HashMap<>();
        result.put("rows",rows);
        return JSONResult.ok(result);
    }

    @PostMapping("/deleteUserByIds")
    @ApiOperation(value = "删除用户",notes = "删除用户", httpMethod = "POST")
    @Log(title = "删除用户", businessType = BusinessType.DELETE)
    @PreFuncAuth("SYS:USER:DELETE")
    public JSONResult deleteUserByIds(@Valid @RequestBody DeleteUserByIdsBO deleteUserByIdsBO) {
        Long userId = SecurityUtils.getUserId();
        if (ArrayUtil.contains(deleteUserByIdsBO.getUserIds(), userId)) {
            return JSONResult.errorCustom(ResponseType.DELETE_CURRENT_USER_ERROR);
        }
        int rows = userService.deleteUserByIds(deleteUserByIdsBO.getUserIds());
        HashMap<String,Object> result = new HashMap<>();
        result.put("rows", rows);
        return JSONResult.ok(result);
    }

    @PostMapping("/insertAuthRole")
    @ApiOperation(value = "用户授权角色",notes = "用户授权角色", httpMethod = "POST")
    @PreFuncAuth("SYS:USER:UPDATE")
    public JSONResult insertAuthRole(@Valid @RequestBody InsertUserRoleBO insertUserRoleBO) {
        int rows = userRoleService.insertUserRole(insertUserRoleBO.getUserId(), insertUserRoleBO.getRoleIds());
        HashMap<String,Object> result = new HashMap<>();
        result.put("rows", rows);
        return JSONResult.ok(result);
    }

    /**
     * 根据用户账户查询用户信息
     * @param username 用户账户
     * @return 结果
     */
    @GetMapping("/selectUserByUserName/{username}")
    @PreInnerAuth
    public JSONResult selectUserByUserName(@PathVariable("username") String username){
        User user = userService.selectUserByUserName(username);
        if(user == null){
            return JSONResult.ok(null);
        }
        Set<String> permissions = menuService.getPermission(user);
        LoginUser loginUser = new LoginUser(user,permissions);
        return JSONResult.ok(loginUser);
    }

    /**
     * 用户注册
     * @param registerBO 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册",notes = "用户注册", httpMethod = "POST")
    public JSONResult register(@Valid @RequestBody RegisterBO registerBO){
        checkUtils.checkEmailVerificationCode(registerBO.getEmail(),registerBO.getCheckCode());
        //校验用户账户是否存在
        checkUserExist(registerBO.getUsername());
        User user = JSONUtil.parse(registerBO).toBean(User.class);
        Long userId = IdUtil.getSnowflake().nextId();
        user.setUserId(userId);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        //注册用户
        int rows = userService.registerUser(user);
        if(rows > 0){
            return JSONResult.ok("注册成功");
        }
        return JSONResult.errorCustom(ResponseType.USER_REGISTER_ERROR);
    }

    @PostMapping("/resetPassword")
    @ApiOperation(value = "重置密码",notes = "重置密码", httpMethod = "POST")
    @PreFuncAuth("SYS:USER:RESET:PASSWORD")
    public JSONResult resetPassword(@Valid @RequestBody ResetPasswordBO resetPasswordBO){
        int rows =userService.updatePasswordByUserIds(resetPasswordBO.getUserIds());
        HashMap<String,Object> result = new HashMap<>();
        result.put("rows", rows);
        return JSONResult.ok(result);
    }



    /**
     * 校验用户账户是否存在
     * @param username 用户账户
     */
    private void checkUserExist(String username){
        // 查询用户名是否存在
        boolean isExist = userService.selectUsernameIsExist(username);
        if(isExist){
            GraceException.display(ResponseType.USER_EXIST_ERROR);
        }
    }

}
